package com.ungao.framework.session;

import com.ungao.framework.executor.Executor;
import com.ungao.framework.mapping.Configuration;
import com.ungao.framework.mapping.MapperStatement;
import com.ungao.framework.proxy.MapperProxy;

import java.lang.reflect.Proxy;
import java.util.List;

public class SqlSession {

    private Configuration configuration;

    private Executor executor;

    public SqlSession(Configuration configuration, Executor executor) {
        this.configuration = configuration;
        this.executor = executor;
    }

    /**
     * 获取Mapper接口代理对象
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> T getMapper(Class<T> clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader()
                , new Class[]{clazz}
                , new MapperProxy(this));
    }

    /**
     * 执行新增
     *
     * @param statementKey
     * @param args
     * @return
     */
    public int insert(String statementKey, Object[] args) {
        MapperStatement mapperStatement = this.configuration.getMapperStatements().get(statementKey);
        return this.executor.insert(mapperStatement, args);
    }

    /**
     * 执行删除
     *
     * @param statementKey
     * @param args
     * @return
     */
    public int delete(String statementKey, Object[] args) {
        MapperStatement mapperStatement = this.configuration.getMapperStatements().get(statementKey);
        return this.executor.delete(mapperStatement, args);
    }

    /**
     * 执行修改
     *
     * @param statementKey
     * @param args
     * @return
     */
    public int update(String statementKey, Object[] args) {
        MapperStatement mapperStatement = this.configuration.getMapperStatements().get(statementKey);
        return this.executor.update(mapperStatement, args);
    }

    /**
     * 执行查询
     *
     * @param statementKey
     * @param args
     * @param <T>
     * @return
     */
    public <T> T selectOne(String statementKey, Object[] args) {
        List<T> resultList = this.selectList(statementKey, args);
        if (null != resultList && resultList.size() > 1) {
            throw new RuntimeException("more than one result set!");
        } else {
            return resultList.get(0);
        }
    }

    /**
     * 执行查询
     *
     * @param statementKey
     * @param args
     * @param <T>
     * @return
     */
    public <T> List<T> selectList(String statementKey, Object[] args) {
        MapperStatement mapperStatement = this.configuration.getMapperStatements().get(statementKey);
        return this.executor.query(mapperStatement, args);
    }
}
